home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Merciful 2
/
Merciful - Disc 2.iso
/
software
/
a
/
alliancedoc's03.dms
/
alliancedoc's03.adf
/
CHAP7_1.DOC.pp
/
CHAP7_1.DOC
Wrap
Text File
|
1992-02-22
|
27KB
|
789 lines
________________________________________________________________________
/ \
| ALLIANCE Presents : Amiga Graphics Inside and Out. |
| The complete Book from Abacus. |
| |
| Typed By : Razor Blade. |
| Supplied By : Viper. |
| |
| ALLIANCE ARE : Alchemist, Aramis, Barbarian, CI/\RS, Chaos, Glitch, Mit, |
| Raistlin, Razor Blade, ShadowFax and Viper. |
| |
\________________________________________________________________________/
/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\
> <
> CALL OUR WORLD HQ N-O-W : UNKNOWN PLEASURES : +44 823 322891 <
> <
\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//
CHAPTER 7 - THE IFF-ILBM STANDARD
=================================
"IFF" is the abbreviation for "Interchange File Format. This format evolved
from an agreement between two companies, Electronic Arts and Commodore when
the Amiga was just being introduced. These companies decided that it would
not be practical for users or programmers if each graphic program saved
graphics in a different format. If this happened then it is possible that
Graphicraft or Aegis pictures would only work with Aegis software. Without
a
a standard format exchanging pictures between programs would be impossible.
This is the reason why the standard format ILBM (InterLeave BitMap) was
created. An ILBM file consists of many components. The following are the
most important:
'BMHD' = BitMapHeaDer.
Identification: BMHDnnnn
Offset Type Description.
------- -------- -----------------------------------------------------
+000 Word Width of graphic.
+002 Word Height of graphic.
+004 Word X position this graphic.
+006 Word Y position this graphic.
+008 Byte Number of bitplanes (depth)
+009 Byte Masking
0 = No Masking.
1 = MAsking.
2 = Transparent.
3 = Lasso.
+010 Byte Data compression.
0 = No Compression.
1 = ByteRun1 algorithm.
+011 Byte Unused.
+012 Word "transparent" colour.
+014 Byte X aspect.
+015 Byte Y aspect.
+016 Word Width of Source Page.
+018 Word Height of Source Page.
PAGE 279
---------------------------------------------------------------------------
"CMAP" = ColorMap
Identification: CMAPnnnn
Offset Type Description
------- ------- ----------------------------------------------------------
+001 Byte Red (0-255)
+002 Byte Green (0-255)
+003 Byte Blue (0-255)
"BODY" = Bit-Planes.
Identification: BODYnnn
-----------------------------------------------------
Bit-plane 1
Bit-Plane 2
(...)
Bit-Plane n
------------------------------------------------------
"CAMG" = Amiga ViewPort Mode (Hires, lores, Lace, etc...)
Identificiation: CAMGnnnn
Offset Type Description
------- ------- ------------------------------------------------------
+000 Long ViewPort Mode (see chapter 4).
----------------------------------------------------------------------
Same as the color cycle information from GraphiCraft:
"CCRT" - raphiCraft ColorCycle Data.
Identification: "CCRTnnnn"
Offset Type Description.
------- ------- ----------------------------------------------
+000 Word Direction.
0 = Backwards.
1 = Forwards.
+002 Byte Start (number of colour register; 0-31)
+003 Byte End (number of colour register; 0-31)
+004 Long Seconds.
+008 Long Micro Seconds.
---------------------------------------------------------------
These important data blocks represent the ILBM format file for every
graphic saved using this method.
The folowing program demonstrates how to load and display this type of
file. It is possible for you to load any ILBM graphic that you want. For
example, you can load a graphic that was created with your drawing program
or an ILBM graphic from any other type of program.
PAGE 280
---------------------------------------------------------------------------
'####################################################
'#
'# Section: 7
'# Program: Load ILBM picture from disk.
'# Date : 01/15/87
'# Author : TOB
'# Version: 1.0
'#
'# Loads pictures of any mode, including HAM, halfbrite and
'# any GraphiCraft Color Cycle.
'#
'# Based on ILBM IFF Interleaved Bitmap Standard published November
'# 15, 1985 in the Rom kenal manual.
'#
'#######################################################
PRINT "Searching for .bmap files ........ "
'DOS-library
DECLARE FUNCTION xOpen& LIBRARY
DECLARE FUNCTION xRead& LIBRARY
DECLARE FUNCTION Seek& LIBRARY
'xClose()
'Delay()
'EXEC-library
DECLARE FUNCTION AllocMem& LIBRARY
DECLARE FUNCTION DoIO% LIBRARY
DECLARE FUNCTION OpenDevice% LIBRARY
DECLARE FUNCTION AllocSignal% LIBRARY
DECLARE FUNCTION FindTask& LIBRARY
'FreeMem()
'GRAPHICS-library
DECLARE FUNCTION AllocRaster& LIBRARY
'SetRast()
'LoadRGB4()
LIBRARY "dos.library"
LIBRARY "exec.library"
LIBRARY "graphics.library"
main: '* LOAD
PAGE 281
---------------------------------------------------------------------------
CLS
PRINT "ILBM Loader"
PRINT
PRINT "Loads Standard IFF Graphic Files into"
PRINT "memory and displays the Picture."
PRINT
PRINT "The IFF Loader supports GraphiCraft color cycling,"
PRINT " the display of Hold-and-Modify (4096 colors)"
PRINT " and Halfbrite (64 colours)."
PRINT
PRINT "In accordance with the ILBM standards it decodes packed"
PRINT "graphic files that use the ByteRun1 method and "
PRINT "displays them."
PRINT
PRINT "If desired, you can print the picture on a graphics"
PRINT " capable printer."
LINE INPUT "Name of IBM File : ";ilbm.file$
LINE INPUT "Do you wantthe picture printed (Y/N) ? ";yn$
LoadILBM ilbm.file$
ColorCycle -1
IF yn$ = "y" THEN
WINDOW OUTPUT 2
Hardcopy
END IF
WHILE INKEY$ = "":WEND
ILBMend
LIBRARY CLOSE
Sub LoadILBM(ilbm.name$) STATIC
SHARED disk.handle&, buf.read&
SHARED buf.color&, but.rgb&
SHARED ilbm.error$, signal%
SHARED screen.kolor%, amiga.viewport&
SHARED ilbm.vp.mode&
SHARED amiga.rastport&
disk.modeOldFile% = 1005
disk.name$ = ilbm.name+CHR$(0)
'* Open ILBM file
disk.handle& = xOpen&(SADD(disk.name%),1005)
IF disk.handle& = 0 THEN
PAGE 282
---------------------------------------------------------------------------
ilbm.error$ = "ILBM File "+ilbm.name$+" not on specified disk
and drawer. "
GOTO ilbm.error.A
END IF
'* Setup disk read buffer.
mem.opt& = 2^0+2^16
buf.size& = 240
buf.add& = AllocMem&(buf.size&,mem.opt&)
IF buf.add& = 0 THEN
ilbm.error$ = "Not enough buffer memory free."
GOTO ilbm.error.A
END IF
'* Section buffer for chunk areas.
buf.read& = buf.add&+0*120
buf.rgb& = buf.add&+1*120
'* Is it an ILBM file ???
disk.wasread& = xRead&(disk.handle&,buf.read&,12)
ilbm.ID.$ = ""
FOR loop1% = 8 TO 11
ilbm.ID.$ = ilbm.ID.$ + CHR$(PEEK,buf.read&+loop1%))
NEXT loop1%
IF ilbm.ID.$ <> "ILBM" THEN
ilbm.error$ = "File ":+ilbm.name$+" is not an ILBM file."
GOTO ilbm.error.A
END IF
'* read data chunks from ILBM
WHILE (signal%<>1) AND (ilbm.error$ = "")
ReadChunk
WEND
'* Error ?
ilbm.error.A:
IF ilbm.error$<>"" THEN
WINDOW CLOSE 2
SCREEN CLOSE 1
PRINT ilbm.error$
EXIT SUB
END IF
'* All ok
CALL LoadRGB4(amiga.viewport&, buf.rgb&, screen.kolor%)
'* Close ILBM file?
IF disk.handle & <> 0 THEN
CALL xClose(disk.handle&)
END IF
IF buf.add& <> 0 THEN
CALL FreeMem(buf.add&,buf.size&)
PAGE 283
---------------------------------------------------------------------------
buf.add& = 0
END IF
'* Set ViewModes.
POKEW amiga.viewport&+32, ilbm.vp.mode&
END SUB
SUB ILBMend STATIC
WINDOW CLOSE 2
SCREEN CLOSE 1
END SUB
SUB ColorCycle(mode%) STATIC
SHARED ccrt.direction%
SHARED ccrt.start%, amiga.colortable&
SHARED ccrt.end%, screen.kolor%
SHARED ccrt.secs&, status%
SHARED ccrt.mics&, amiga.viewport&
'* As intended.
IF (status% AND 2^4) <> 2^4 THEN
EXIT SUB
END IF
'* Setup varaible field
DIM kolor.original%(screen.kolor%-1)
DIM kolor.actual%(screen.kolor%-1)
'* all OK, save old color from ViewPort.
FOR loop1% = 0 TO screen.kolor%-1
kolor.original%(loop1%) = PEEKW(amiga.colortable&+2*loop1%)
kolor.actual%(loop1%) = kolor.original%(loop1%)
NEXT loop1%
'* Colour cycling.
WHILE mode%<>0
'* Mode ?
IF mode% < 0 THEN
in$ = INKEY$
IF in$<>"" THEN mode% = 0
ELSE
mode% = mode% - 1
END IF
'* Forwards ?
IF ccrt.direction% = 1 THEN
ccrt.backup% = kolor.actual%(ccrt.start%)
FOR loop1% = ccrt.start%+1 TO ccrt.end%
kolor.actual%(loop1%-1)=kolor.actual%(loop1%)
NEXT loop1%
kolor.actual%(ccrt.end%) = ccrt.backup%
'* Backwards.
ELSE
PAGE 284
---------------------------------------------------------------------------
ccrt.backup% = kolor.actual%(ccrt.end%)
FOR loop1% = ccrt.start%-1 TO ccrt.end% STEP -1
kolor.actual%(loop1%+1) = kolor.actual%(loop1%)
NEXT loop1%
kolor.actual%(ccrt.start%) = ccrt.backup%
END IF
CALL LoadRGB4(amiga.viewport&,VARPTR(kolor.actual%(0)),
screen.kolor%)
timeout& = 50*(ccrt.secs&+(ccrt.mics&/1000000&))
CALL Delay(timeout&)
WEND
'* Restore original colors.
CALL LoadRGB4(amiga.viewport&,VARPTR(kolor.original%(0)),screen.kolor%)
'* REturn fields.
ERASE kolor.original%
ERASE kolor.actual%
END SUB
SUB ReadChunk STATIC
SHARED disk.handle&, buf.read&
SHARED buf.color&, buf.rgb&
SHARED ilbm.error$, signal%
SHARED screen.kolor%, amiga.viewport&
SHARED ilbm.vp.mode&, status%
SHARED amiga.rastport&
SHARED ccrt.direction%
SHARED ccrt.start%, amiga.colortable&
SHARED ccrt.end%, screen.kolor%
SHARED ccrt.secs&
SHARED ccrt.mics&
'* Read chunk header.
disk.wasread& = xRead&(disk.handle&, buf.read&, 8)
ilbm.chunk& = PEEKL(buf.read&+4)
ilbm.ID.$ = ""
FOR loop1% = 0 TO 3
ilbm.ID.$ = ilbm.ID.$+CHR$(PEEK(buf.read&+loop1%))
NEXT loop1%
'* The bitmap Header (BMHD) ?
IF ilbm.ID.$ = "BMHD" THEN
'* Read chunk contents.
disk.wasread& = xRead&(disk.handle&,buf.read&,ilbm.chunk&)
status% = status% OR 2^0
ilbm.width% = PEEKW(buf.read&+0)
ilbm.height% = PEEKW(buf.read&+2)
ilbm.depth% = PEEK(buf.read&+8)
ilbm.mode% = PEEK(buf.read&+10)
PAGE 285
---------------------------------------------------------------------------
screen.width& = PEEKW(buf.read&+16)
screen.height% = PEEKW(buf.read&+18)
'* Build Display Parameters.
ilbm.bytes% = ilbm.width%/8
screen.bytes% = screen.width%/8
screen.kolor% = 2^(ilbm.depth%)
'* prepare for our display.
'* Hires (Hi resolution ? )
IF screen.width%>320 THEN
screen.mode% = 2
ELSE
screen.mode% = 1
END IF
'* Interlace (y = 0 - 399)
IF screen.height%>200 THEN screen.mode% = screen.mode%+2
'* ILBM depth% = 6 -> HAM/Halfbrite ?
IF ilbm.depth% = 6 THEN
ilbm.re% = -1
END IF
depth% = ilbm.depth%+ilbm.reg%
SCREEN 1,screen.width%,screen.height%,depth%,screen.mode%
WINDOW 2,,,0,1
'* System parameters
amiga.windo& = WINDOW(7)
amiga.screen& = PEEKL(amiga.windo&+46)
amiga.viewport& = amiga.screen&+44
amiga.rastport& = amiga.screen&+84
amiga.colormap& = PEEKL(amiga.viewport&+4)
amiga.colortable& = PEEKL(amiga.colormap&+4)
amiga.bitmap& = PEEKL(amiga.rastport&+4)
FOR loop1% = 0 TO ilbm.depth%-1
amiga.plane&(loop1%) = PEEKL(amiga.bitmap&+8+loop1%*4)
NEXT loop1%
'* For HAM/Halfbrite prepare 6 bitplanes.
IF ilbm.reg% = -1 THEN
ilbm.reg% = 0
newplane& = ALlocRaster&(screen.width%,screen.height%)
IF newplane& = 0 THEN
ilbm.error$ = "Not enough memory free for 6 bitplanes!"
ELSE
POKE amiga.bitmap&+5,6
POKEL amiga.bitmap&+28,newplane&
END IF
PAGE 286
---------------------------------------------------------------------------
END IF
;* ColorTable (CMAP)?
ELSE IF ilbm.ID.$ = "CMAP" THEN
'* REad chunk contents.
disk.wasread& = xRead&(disk.handle&,buf.read&,ilbm.chunk&)
status = status% OR 2^1
'* Calculate RGB table.
FOR loop1% = 0 TO screen.kolor% - 1
kolor.red% = PEEK(buf.read&+loop1%*3+0)
kolor.green%=PEEK(buf.read&+loop1%*3+1)
kolor.blue% =PEEK(buf.read&+loop1%*3+2)
kolor.rgb% = kolor.green%+16*kolor.red%+1/16*kolor.blue%
POKEW buf.rgb&+2*loop1%,kolor.rgb%
NEXT loop1%
'* Alignment.
IF (ilbm.chunk OR 1)=ilbm.chunk THEN
disk.wasread&=xRead&(disk.handle&,buf.read&,1)
END IF
'* Viewport Mode (CAMG) AMIGA ?
ELSE IF
ELSE IF ilbm.ID.$ = "CAMG" THEN
'* Read chunk contents.
disk.wasread& = xRead&(disk.handle&, buf.read&, ilbm.chunk&)
status% = status% OR 2^4
ccrt.direction% = PEEKW(buf.read&+0)
ccrt.start% = PEEK (buf.read&+2)
ccrt.end% = PEEK (buf.read&+3)
ccrt.secs& = PEEKL (buf.read&+4)
ccrt.mics& = PEEKL(buf.read&+8)
'* Bitplanes (BODY) ?
ELSEIF ilbm.ID.$ = "BODY" THEN
status% = status% OR 2^2
'* not compressed data.
IF ilbm.mode% = 0 THEN
FOR loop1% = 0 TO ilbm.height%-1
FOR loop2% = 0 TO ilbm.depth%-1
PAGE 287
---------------------------------------------------------------------------
screen.buffer& =amiga.plane&(loop2%)+(loop1%*
screen.bytes%)
disk.wasread& = xRead&(disk.handle&,screen.buffer&,
ilbm.bytes%)
NEXT loop2%
NEXT loop1%
'* Compressed Data (ByteRun1-Encoding)
ELSEIF ilbm.mode% = 1 THEN
FOR loop1% = 0 TO ilbm.height%-1
FOR loop2% = 0 TO ilbm.depth%-1
screen.buffer& = amiga.plane&(loop2%)+(loop1%*
screen.bytes%)
counter% = 0
'* Decoding.
WHILE counter% <ilbm.bytes%
disk.wasread& = xRead&(disk.handle&,buf.read&,1)
code% = PEEK(buf.read&)
'* Code 1: read n bytes uncoded.
IF code% < 128 THEN
disk.wasread& =
xRead&(disk.handle&,screen.buffer&+counter%,code%+1)
counter% = counter%+code%+1
'* Code 2 Repeat bytes (257-n) times.
ELSEIF code% > 128 THEN
disk.wasread& = xRead&(disk.handle&,buf.read&,1)
disk.byte% = PEEK(buf.read%)
FOR loop3% = counter% TO counter%+257-code%
POKE screen.buffer&+loop3%,disk.byte%
NEXT loop3%
counter% = counter%+257-code%
'* Code 3 : no operation.
ELSE
'* no operation.
END IF
WEND
NEXT loop2%
NEXT loop1%
'* Different decoding method.
ELSE
ilbm.error$ = "Data compression algorithm unknown. "
END IF
'* Process unimportant chunks. (GRAB, DEST, SPRT, etc...)
ELSE
;* Read straigh count bytes.
IF (ilbm.chunk% OR 1)=ilbm.chunk% THEN
ilbm.chunk%=lib.chunk%+1
PAGE 288
---------------------------------------------------------------------------
END IF
'*Move Disk cursor.
mode.current% = 0
stat& = Seek&(disk.handle&,ilbm.chunk%,0)
IF stat& = -1 THEN
ilbm.error = "DOS error. Seek() failed."
END IF
END IF
'* Error check.
IF disk.wasread& < - THEN
ilbm.error$ = "DOS Error. Read() Failed."
'* EOF (end of file) reached ?
ELSEIF disk.wasread& = 0 AND ((status% AND 7) <> 7 THEN
ilbm.error$ = "ILBM data chunks not present."
signal% = 1
ELSEIF (status% AND 7) = 7 THEN
signal% = 1
END IF
END SUB
SUB Hardcopy STATIC
mem.opt& = 2^0+2^16
p.io& = AllocMem&(100,mem.opt&)
p.port& = p.io&+62
IF p.io& = 0 THEN ERROR 7
f.windo& = WINDOW(7)
f.rastport& = PEEKL(f.windo&+50)
f.width% = PEEKW(f.windo&+112)
f.height% = PEEKW(f.windo&+114)
f.screen& = PEEKL(f.windo&+46)
f.viewport& = f.screen&+44
f.colormap& = PEEKL(f.viewport&+4)
f.vp.mode% = PEEKW(f.viewport&+32)
p.sigBit% = AllocSignal%(-1)
IF p.sigBit% = -1 THEN
PRINT "No Signalbit free!"
CALL FreeMem(p.io&,100)
EXIT SUB
END IF
p.sigTask& = FindTask&(0)
POKE p.port&+8,4
POKE p.port&+10,p.port&+34
POKE p.port&+15,p.sigBit%
POKEL p.port&+16,p.sigTask&
POKEL p.port&+20,p.port&+24
PAGE 289
---------------------------------------------------------------------------
POKEL p.port&+28,p.port&+20
POKE p.port&+34,ASC("P")
POKE p.port&+35,ASC("R")
POKE p.port&+36,ASC("T")
CALL AddPort(p.port&)
POKE p.io&+8,5
POKEL p.io&+14,p.port&
POKEW p.io&+28,11
POKEL p.io&+32,f.rastport&
POKEL p.io&+36,f.colormap&
POKEL p.io&+40,f.vp.mode%
POKEW p.io&+48,f.width%
POKEW p.io&+50,f.height%
POKEL p.io&+52,f.width%
POKEL p.io&+56,f.height%
POKEW p.io&+60,4
d.name$ = "printer.device"+CHR$(0)
status% = OpenDevice%(SADD(d.name$),0,p.io&,0)
IF status% <> 0 THEN
PRINT "Printer is not free":
CALL FreeMem(p.io&,100)
CALL FreeSignal(p.sigBit%)
EXIT SUB
END IF
ercond% = DoIO%(p.io&)
CALL CloseDevice(p.io&)
CALL RemPort(p.port&)
CALL FreeMem(p.io&,100)
CALL FreeSignal(p.sigBit%)
PRINT "Error Code: ";ercond%
END SUB
PROGRAM DESCRIPTION.
====================
The SUB program LoadILBM requires a string containing the name of the ILBM
picture you want to load from disk. The picture must be in the active disk
directory in order for the active program to find it (CHDIR directory). The
Extras diskette for workbench 1.2 contains the Heart.ILBM file, which is
a good example picture to use. This program loads and displays the picture.
Now you could call the SUB program ColorCycle. When this program finds a
CCRT ColorCycle data block, it activates the cycling, which creates a
motion like effect on the screen. This SUB program requires an integer
argument. If the argument is negative, the Amiga cycles the colours until
you press a key. If the argument is positive, the Amiga cycles the colors
for a time period determined by your argument. The SUB program ILBMend
stops the display and closes both the screen and window.
PAGE 290
------------------------------------------------------------------------
The DOS library routines are new in our program. You cannot use the built
in OPEN/INPUT#/CLOSE commands when working with ILBM files because these
commands place zeros in the data. Here is a short explanation of the DOS
routines used:
name$ = name$+CHR$(0)
disk.handle&=xOpen&(SADD(name$),1005)
name$ : Name of file to be opened.
1005 : ModeOldFile - file already exists.
1006 : ModeNewFile - make file with this name.
dis.handle& = BPTR (pointer/4) in handler data block when 0, then
xOpen failed.
=================================
wasread& = xRead(disk.handle&,buffer&,bytes&)
disk.handle& : Address from xOpen call.
buffer& : Address of a free memory area.
bytes& : Number of bytes to be read from the actual disk
cursor position that have to fit in the buffer!
wasread& : Number of bytes read.
=0: EOF (End Of File)
smaller than zero: read error.
======================================
oldpos& = Seek(disk.handle&,offset%,mode%)
disk.handle& : Address from xOpen call.
offset% : Number of bytes to move the disk cursor.
mode% : 0 = From current position.
-1 = From file begin.
1 = From file end.
======================================
CALL xClose(disk.handle&)
disk.handle& : Handle from xOpen command; closes file.
=======================================
CALL delay(ticks)
tick : 1/50/ second.
microseconds : 1/100000 second.
Waits for the specified time (however, this does not mean busy waiting,
the system has additional computing time free).
PAGE 291
---------------------------------------------------------------------------
Special Features of the program:
-------------------------------
This program not only supports the AmigaBASIC display modes hires and
interlace, but also the ILBM graphics in halfbrite (64 colors) and HAM mode
(4096) colours. Both modes use six bitplanes. Whenever one of these modes
is encountered, a sixth bitplane is added to the screen. However, we do not
clear this bitplane using FreeRaster. Instead, when the SCREEN CLOSE
statement closes the new screen, all the bitplanes, including the sixth
bitplane that was added are automatically deleted.
The program is capable of decoding compacted bitplanes by using the
"ByteRun1" method. This method uses two control codes. When the first byte
read is smaller than 128 then the following byte is simply loaded and used.
When the first byte is a value greater than 128, the second byte is
repeated 257 times (normally signed bytes from -127 to +128 are used for a
more complicated compression algorithm). When the byte is equal to 128
nothing happens because it has a NOP (No Operation).
PAGE 292
---------------------------------------------------------------------------